package demo1;

class Shape {
    public void draw() {
//        如果子类对象重写 这里写和没写一样
        System.out.println("Shape::draw()");
    }
}
class Rect extends Shape{
    public void draw(){
        System.out.println("♦");
    }
}
class Flower extends Shape{
    public void draw(){
        System.out.println("❀");
    }
}
class Triangle extends Shape{
    public void draw(){
        System.out.println("▲");
    }
}
class Cycle extends Shape{
//    快捷键
//    鼠标右键-Generate-Override Methods
    @Override
    public void draw() {
        System.out.println("○");
        super.draw();
    }
}





public class Test {

//    多态
//    当类的调用者在编写 drawMap 这个方法的时候, 参数类型为 Shape (父类), 此时在
//    该方法内部并不知道, 也不关注当前的 shape 引用指向的是哪个类型(哪个子类)的实
//    例.此时 shape 这个引用调用 drawMap 方法可能会有多种不同的表现(和 shape 对应
//    的实例相关), 这种行为就称为 多态.

//    使用多态的好处 main3
//    1) 类调用者对类的使用成本进一步降低.
//      封装是让类的调用者不需要知道类的实现细节.
//      多态能让类的调用者连这个类的类型是什么都不必知道, 只需要知道这个对象具有某个方法即可.
//    2) 能够降低代码的 "圈复杂度", 避免使用大量的 if - else
//    3) 可扩展能力更强.
//      如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低
//      对于类的调用者来说(drawShapes方法), 只要创建一个新类的实例就可以了, 改动成本很低.
    public static void drawMap(Shape shape){
        shape.draw();
        //main2中  通过一个引用调用同一个方法 会表现出不同的表现形式 这种行为我们称为多态
//      可以理解为 一种方法多种形态
    }

    public static void main1(String[] args) {
        Rect rect = new Rect();
        rect.draw();
//      向上转型
        Shape shape1 = new Rect();
        shape1.draw();//如果子类重写了draw 那么调用的是子类的draw方法
        System.out.println("===========");
        Shape shape2 = new Flower();
        shape2.draw();
    }


    public static void main2(String[] args) {
        Rect rect = new Rect();
        drawMap(rect);
        drawMap(new Flower());
        drawMap(new Triangle());
//        在调用drawMap过程中 因为这里的类型是Shape类型的子类 所以可以类型不一样
//        通过父类引用 引用不同的对象
    }






//      没使用多态
    public static void drawShapes() {
        Rect rect = new Rect();
        Triangle triangle = new Triangle();
        Flower flower = new Flower();
        String[] shapes = {"▲", "♦", "▲", "♦", "❀"};
        for (String shape : shapes) {
            if (shape.equals("▲")) {
                triangle.draw();
            } else if (shape.equals("♦")) {
                rect.draw();
            } else if (shape.equals("❀")) {
                flower.draw();
            }
        }
    }
//      使用多态
    public static void drawShapes1() {
//        我们创建了一个 Shape 对象的数组.
        Shape[] shapes = {new Triangle(), new Rect(),
                new Triangle(), new Rect(),
                new Flower(), new Cycle()};
        for (Shape shape : shapes) {
            shape.draw();//避免重复多次使用if-else
        }
    }
        public static void main(String[] args) {
//        如果没使用多态 if-else解决此类问题就比较麻烦
            drawShapes();
            System.out.println("=============");
            drawShapes1();
    }



}
